package com.cloud.class04;

import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

public class SocketTest {
    //● 调用 ServerSocket(int port)  ：创建一个服务器端套接字，并绑定到指定端口上。用于监听客户端的请求。
//● 调用 accept() ：监听连接请求，如果客户端请求连接，则接受连接，返回通信套接字对象。
//● 调用  该Socket 类对象的 getOutputStream()  和 getInputStream () ：获取输出流和输入流，开始网络数据的发送和接收。
//● 关闭Socket 对象：客户端访问结束，关闭通信套接字。
    @Test
    public void server() throws IOException {
//        1、创建服务器端ServerSocket，并绑定端口号
        ServerSocket serverSocket = new ServerSocket(8868);
        System.out.println("等待连接.........");
//        2、监听连接，等待连接,该方法是阻塞式的，会一直等待，直到有客户端连接
        Socket socket = serverSocket.accept();
        InetAddress inetAddress = socket.getInetAddress();
        System.out.println("客户端的ip地址：" + inetAddress.getHostAddress() + ":" + socket.getPort() + "连接成功！！！！");
//        3、获取输入流，读取客户端发送的数据
        InputStream inputStream = socket.getInputStream();
//        接受数据
        StringBuilder sb = new StringBuilder();
        int len;
        while ((len = inputStream.read()) != -1) {
            sb.append((char) len);
        }
        System.out.println("客户端发送的数据：" + sb);
//        4、获取输出流，向客户端发送数据
        OutputStream outputStream = socket.getOutputStream();
        outputStream.write("receive".getBytes());
        outputStream.flush();
//        5、关闭socket，不再与客户端通信，释放资源
        socket.close();
        serverSocket.close();


    }

    // ● 创建 Socket ：根据指定服务端的 IP 地址或端口号构造 Socket 类对象。若服务器端响应，则建立客户端到服务器的通信线路。若连接失败，会出现异常。
//● 打开连接到 Socket  的输入/ 出流： 使用 getInputStream()方法获得输入流，使用getOutputStream()方法获得输出流，进行数据传输
//● 按照一定的协议对 Socket 进行读/ 写操作：通过输入流读取服务器放入线路的信息（但不能读取自己放入线路的信息），通过输出流将信息写入线路。
//● 关闭 Socket ：断开客户端到服务器的连接，释放线路
    @Test
    public void client() throws IOException {
//        1、创建客户端Socket，指定服务器的ip和端口号
        Socket socket = new Socket("localhost", 8868);
//        2、获取输出流，向服务器端发送数据
        OutputStream outputStream = socket.getOutputStream();
        //发送数据
        outputStream.write("hello".getBytes());
//       shutdownOutput()此方法是关闭输出流，但是并不关闭socket，仍然可以接收服务器端的数据
        socket.shutdownOutput();
//        3、获取输入流，读取服务器端响应的数据
        InputStream inputStream = socket.getInputStream();
        StringBuilder sb = new StringBuilder();
        int len;
        while ((len = inputStream.read()) != -1) {
            sb.append((char) len);
        }
        System.out.println("服务器端响应的数据：" + sb);
//        4、关闭资源
        inputStream.close();
        outputStream.close();
        socket.close();



    }

}
